﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GcmpModelInterface.h"
#include "IElementParentReporter.h"

namespace gcmp
{
    class IElement;
    class IDocument;
    class UniIdentity;
    class ICalculatorCollection;

    /// \brief Element公用方法
    class GCMP_MODEL_INTERFACE_EXPORT ElementUtils final
    {
    public:
        
        /// \brief 将临时对象转变为永久对象，临时对象会被删除。
        /// \param pDocument 当前文档
        /// \param transientElementId 临时对象Id
        /// \param normalElementId 永久对象Id
        /// \return 转变成功返回true，否则返回false。
        static bool MakeElementNormal(IDocument* pDocument, const ElementId& transientElementId, ElementId& normalElementId);

        /// \brief 将对象转变为唯一对象。
        /// \param pElement 当前对象
        /// \param guid 类的classUid
        /// \return 转变成功返回true，否则返回false。
        static bool MakeElementUnique(IElement* pElement, const UniIdentity& classUid);

        /// \brief 此接口用于对删掉的弱依赖做适当的处理
        ///
        /// 当弱依赖的Element被删除后，此接口会被调用：
        ///   1.移除引用的Element Id。
        ///   2.将引用的Element Id设成无效值。
        ///   3.选用另外一个有意义的Element作引用。
        /// 对于IExternalObject对象来说，平台内部不会默认调用此函数，如果没有定制自己的特殊处理，则需要手动调用此函数才会正确处理弱依赖关系。
        /// \param pElement 表示需要更新数据的Element
        /// \param deleteElementIds 表示将被删除的ElementIds
        /// \return void
        static void UpdateForWeakParentDeletion(IElement* pElement, const std::set<ElementId>& deletedElementIds);

        /// \brief 报告依赖的ElementIds
        ///
        /// 对于IExternalObject对象来说，平台内部不会默认调用此函数，如果没有定制自己的特殊处理，则需要手动调用此函数才会正确报告依赖的ElementIds
        /// 元素删除和关联更新依赖于这个接口的正确实现:
        ///   1. 报告强依赖IElement(ElementParentReporter::ReportStrong): 强依赖IElement被删除，此IElement也会自动被系统删除。
        ///   2. 报告弱依赖IElement(ElementParentReporter::ReportWeak)：弱依赖IElement被删除，此IElement会通过UpdateForWeakParentDeletion得到通知。
        /// 依赖ElementIds的来源主要有两个:
        ///   1. IElement属性直接或间接引用的Id。
        ///   2. 用到的全局的ElementId。
        /// \param pElement 表示需要更新数据的Element
        /// \param elementParentReporter Element关系报告器
        /// \return void
        static void ReportParents(const IElement* pElement, IElementParentReporter& elementParentReporter) ;

        /// \brief 报告Element的平台内部计算器
        ///
        /// 此接口会收集参数绑定的计算器， 定位相关的高度计算器以及Element对象外部数据（IExternalData）计算器
        /// 对于IExternalObject对象来说，平台内部不会默认调用此函数，外部定制IElementRegenerationComponent，需要累加平台行时，可以调用此函数。
        ///  
        /// \param pElement IElement对象
        /// \param calculators 计算器收集器指针
        /// \return void
        static void GetCalculators(const IElement* pElement, ICalculatorCollection* pCalculators);

        /// \brief 判断Element是否是代理对象
        /// \param pElement 对象指针，传入空返回false
        /// \return 是-true;否-false
        static bool IsProxyElement(const IElement* pElement);
    };
}


